﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Windows.Input;
using System.Xml.Serialization;
using UIConfigTool.ViewModel;

namespace UIConfigTool.Models.CDS
{
    [XmlInclude(typeof(Heater))]
    [XmlInclude(typeof(Valve))]
    [XmlInclude(typeof(InletPipe))]
    [XmlInclude(typeof(FlowControl))]
    [XmlInclude(typeof(FlowMeter))]
    public class DeviceBase : INotifyPropertyChanged
    {
        public DeviceBase() { }
        private string id;

        [XmlAttribute("Id")]
        public string Id
        {
            get { return id; }
            set
            {
                if (id != value)
                {
                    id = value;
                    OnPropertyChanged(nameof(Id));
                }
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

    }

    public class Heater : DeviceBase
    {
    }

    public class Valve : DeviceBase
    {
    }
    public class FlowControl : DeviceBase
    {
    }
    public class FlowMeter : DeviceBase
    {
    }

    public class InletPipe : DeviceBase
    {

        [XmlArray("Valves")]
        [XmlArrayItem("Valve")]
        public List<Valve> Valves { get; set; } = new List<Valve>();
        [XmlArray("FlowControls")]
        [XmlArrayItem("FlowControl")]
        public List<FlowControl> FlowContols { get; set; } = new List<FlowControl>();
        [XmlArray("FlowMeters")]
        [XmlArrayItem("FlowMeter")]
        public List<FlowMeter> FlowMeters { get; set; } = new List<FlowMeter>();
    }

    public class CDSDevice : DeviceNode
    {
        private bool _hasDrainBox;
        private bool _hasReturnPipe;
        private bool _hasDirectSupplyPipe;
        private bool _hasFlowControl;
        private bool _hasCoolingWater;
        private bool _hasSpiking;
        private bool _hasLiquidChangeFunction;
        [XmlIgnore]
        public int HeaterCount
        {
            get { return Heaters.Count; }
        }


        [XmlAttribute("HasDrainBox")]
        public bool HasDrainBox
        {
            get => _hasDrainBox;
            set
            {
                if (_hasDrainBox != value)
                {
                    _hasDrainBox = value;
                    OnPropertyChanged(nameof(HasDrainBox));
                }
            }
        }

        [XmlAttribute("HasReturnPipe")]
        public bool HasReturnPipe
        {
            get => _hasReturnPipe;
            set
            {
                if (_hasReturnPipe != value)
                {
                    _hasReturnPipe = value;
                    OnPropertyChanged(nameof(HasReturnPipe));
                }
            }
        }
        [XmlAttribute("HasDirectSupplyPipe")]
        public bool HasDirectSupplyPipe
        {
            get => _hasDirectSupplyPipe;
            set
            {
                if (_hasDirectSupplyPipe != value)
                {
                    _hasDirectSupplyPipe = value;
                    OnPropertyChanged(nameof(HasDirectSupplyPipe));
                }
            }
        }
        [Browsable(false)]
        [XmlArray("Heaters")]
        [XmlArrayItem("Heater")]
        public ObservableCollection<Heater> Heaters { get; set; } = new ObservableCollection<Heater>();
        [Browsable(false)]

        [XmlArray("InletPipes")]
        [XmlArrayItem("InletPipe")]
        public ObservableCollection<InletPipe> InletPipes { get; set; } = new ObservableCollection<InletPipe>();
        [XmlIgnore]
        public override ObservableCollection<DeviceBase> ChildNode { get; } = new ObservableCollection<DeviceBase>();

        [XmlAttribute("HasFlowControl")]
        public bool HasFlowControl
        {
            get => _hasFlowControl;
            set
            {
                if (_hasFlowControl != value)
                {
                    _hasFlowControl = value;
                    OnPropertyChanged(nameof(HasFlowControl));
                }
            }
        }

        [XmlAttribute("HasCoolingWater")]
        public bool HasCoolingWater
        {
            get => _hasCoolingWater;
            set
            {
                if (_hasCoolingWater != value)
                {
                    _hasCoolingWater = value;
                    OnPropertyChanged(nameof(HasCoolingWater));
                }
            }
        }

        [XmlAttribute("HasSpiking")]
        public bool HasSpiking
        {
            get => _hasSpiking;
            set
            {
                if (_hasSpiking != value)
                {
                    _hasSpiking = value;
                    OnPropertyChanged(nameof(HasSpiking));
                }
            }
        }

        [XmlAttribute("HasLiquidChangeFunction")]
        public bool HasLiquidChangeFunction
        {
            get => _hasLiquidChangeFunction;
            set
            {
                if (_hasLiquidChangeFunction != value)
                {
                    _hasLiquidChangeFunction = value;
                    OnPropertyChanged(nameof(HasLiquidChangeFunction));
                }
            }
        }
        [Browsable(false)]
        [XmlIgnore]
        public ICommand AddHeaterCommand { get; private set; }
        [XmlIgnore]
        [Browsable(false)]
        public ICommand AddValveCommand { get; private set; }
        [XmlIgnore]
        [Browsable(false)]
        public ICommand AddInletPipeCommand { get; private set; }
        public CDSDevice()
        {
            Id = "CDS";
            AddHeaterCommand = new RelayCommand<DeviceNode>(AddHeater);
            AddValveCommand = new RelayCommand<DeviceNode>(AddValve);
            AddInletPipeCommand = new RelayCommand<DeviceNode>(AddInletPipe);
            ChildNode.CollectionChanged += ChildNode_CollectionChanged;
        }

        private void ChildNode_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            switch (e.Action)
            {
                case NotifyCollectionChangedAction.Add:
                    foreach (var item in e.NewItems)
                    {
                        if (item is Heater heater)
                        {
                            Heaters.Add(heater);
                        }
                        else if (item is InletPipe pipe)
                        {
                            InletPipes.Add(pipe);
                        }
                    }
                    break;

                case NotifyCollectionChangedAction.Remove:
                    Console.WriteLine("移除了元素:");
                    foreach (var item in e.OldItems)
                    {
                        if (item is Heater heater)
                        {
                            Heaters.Remove(heater);
                        }
                        else if (item is InletPipe pipe)
                        {
                            InletPipes.Remove(pipe);
                        }
                    }
                    break;

                case NotifyCollectionChangedAction.Replace:
                    Console.WriteLine("替换了元素:");
                    break;

                case NotifyCollectionChangedAction.Move:
                    Console.WriteLine("移动了元素");
                    break;

                case NotifyCollectionChangedAction.Reset:
                    Console.WriteLine("集合已清空");
                    break;
            }
        }

        void AddHeater(DeviceNode obj)
        {
            Heater ht = new Heater() { Id = "HT101" };
            obj.ChildNode.Add(ht);
        }
        void AddValve(DeviceNode obj)
        {
            obj.ChildNode.Add(new Valve() { Id = "AV101" });
        }
        void AddInletPipe(DeviceNode obj)
        {
            obj.ChildNode.Add(new InletPipe() { Id = "HF" });
        }
    }


}
